//******************************************************************/
//版本说明:
//V0.5		2010-10-27	22:35	yshao
//				双口sram改为使用swsr16_8_ddp，添加原来没有的输出时钟端口
//******************************************************************/
module state_ctrl_02(
		input   wire            resetb,
        	input   wire            sclk,

		//千兆PHY接口
		input	wire		rec_flag,
		input	wire		rec_error,
	        
		//和通讯模块接口
		input	wire	[15:0]	set_addr,
		input	wire		set_d_ok,
		input	wire	[7:0]	set_data,
		
		//状态寄存器
		input	wire		fpga_sta_active,
		input	wire	[7:0]	state_addr,
		output 	wire	[7:0]	state_data,
		input	wire		fpga_rec_flag,
		
		output	wire	[4:0]	dmx_ack_raddr,
		input	wire	[7:0]	dmx_ack_rdata,
		
		input	wire	[15:0]	bad_p_max,
		//输出给led灯和输出控制模块
		output 	reg		black_mark
		);

//******************************************************************/
//			   信号定义
//******************************************************************/		
//程序版本信息
parameter       main_function   =       8'h53;   //ASCII "S"
parameter       sub_function    =       8'h47;   //ASCII "G"
parameter       main_solution   =       8'd8;    //"8"       
parameter       sub_solution    =       8'd3;    //"03"
parameter       application_type=       8'h84;   //ASCII "T"
parameter       main_version    =       8'd7;    //"07"
parameter       sub_version     =       8'd47;   //X"47"       


reg		rec_flag_t;
reg	[2:0]	counter,counter_t,counter_tt;
reg		add_flag,add_flag_t,add_flag_tt;
reg		clr_flag,clr_flag_t;
reg		load_flag,load_flag_t;
reg	[8:0]	adder;
reg		cin;
reg		buf_wea;
reg	[3:0]	buf_waddr;
reg	[7:0]	buf_wdata;
reg	[3:0]	buf_raddr;
wire	[7:0]	buf_rdata;
reg     [7:0]   state_version;

reg	[15:0]	crc_error_sum_1,crc_error_sum_2;
reg	[31:0]	pkt_sum_1,pkt_sum_2;
reg	[7:0]	data_out;
reg		full_crc;
reg		full_pkt;
always@(posedge sclk, negedge resetb)
	if(!resetb)
		rec_flag_t<=1'b0;
	else
		rec_flag_t<=rec_flag;



//
always@(posedge sclk)
	if(set_addr==16'h0000 && set_d_ok && set_data==8'h00 && fpga_rec_flag=='d1)
		clr_flag<=1'b1;
	else 
		clr_flag<=1'b0;

//		
always@(posedge sclk)
	if(set_addr==16'h0000 && set_d_ok && set_data==8'h02)
		load_flag<=1'b1;
	else load_flag<=1'b0;
always @(posedge sclk)
	if(clr_flag)
		pkt_sum_1<='d0;
	else if(rec_flag_t=='d0 && rec_flag=='d1 && full_pkt=='d0)//pkt_sum_1<32'HFFFF_FFFF)
		pkt_sum_1<=pkt_sum_1+'d1;
always @(posedge sclk)
	if(clr_flag)
		crc_error_sum_1<='d0;
	else if(rec_flag_t=='d0 && rec_flag=='d1 && rec_error=='d1 && full_crc=='d0)//crc_error_sum_1<16'HFFFF)
		crc_error_sum_1<=crc_error_sum_1+'d1;
always @(posedge sclk)
	if((&crc_error_sum_1[15:1])=='d1)
		full_crc<='d1;
	else 
		full_crc<='d0;
always @(posedge sclk)
	if((&pkt_sum_1[31:1])=='d1)
		full_pkt<='d1;
	else 
		full_pkt<='d0;		
always @(posedge sclk)
	if(clr_flag)
		pkt_sum_2<='d0;
	else if(load_flag)
		pkt_sum_2<=pkt_sum_1;

always @(posedge sclk)
	if(clr_flag)
		crc_error_sum_2<='d0;
	else if(load_flag)
		crc_error_sum_2<=crc_error_sum_1;
		
always @(posedge sclk)
	if(fpga_sta_active==1)
	begin
		if(state_addr>=8'h80 && state_addr<=8'h9f)
			data_out<=dmx_ack_rdata;
		else
			case(state_addr)
				'd0:data_out<=crc_error_sum_2[7:0];
				'd1:data_out<=crc_error_sum_2[15:8];
				'd2:data_out<=pkt_sum_2[7:0];
				'd3:data_out<=pkt_sum_2[15:8];
				'd4:data_out<=pkt_sum_2[23:16];
				'd5:data_out<=pkt_sum_2[31:24];
				'h40:data_out<=main_function;
				'h41:data_out<=sub_function;
				'h42:data_out<=main_solution;
				'h43:data_out<=sub_solution;
				'h44:data_out<=application_type;
				'h45:data_out<=main_version;
				'h46:data_out<=sub_version;
		//		'h80:data_out<=bad_p_max[7:0];
		//		'h81:data_out<=bad_p_max[15:8];
				default data_out<='d0;
			endcase
	end

assign dmx_ack_raddr=state_addr[4:0];
	
//always@(posedge sclk or negedge resetb)
//        if(resetb==0)
//                state_version<=8'h0;
//        else if(state_addr[7:4]==4'h4 && state_addr[3]==0)
//                case(state_addr[2:0])
//                0:      state_version   <= main_function;              
//                1:      state_version   <= sub_function;
//                2:      state_version   <= main_solution;
//                3:      state_version   <= sub_solution;
//                4:      state_version   <= application_type;
//                5:      state_version   <= main_version;
//                6:      state_version   <= sub_version;
//                default:        state_version<= 8'h00;
//        endcase
    
assign    state_data=data_out;

//**************************************************************
//辅助定位：通过定点写MEM控制是否本分控辅助定位，
//set_addr==16’h06的低4位的值等于4’hE时辅助定位有效，黑屏、红灯闪。
//软件开启本分控的辅助定位后，需要关闭本分控的辅助定位再进行其它操作。
always	@(posedge sclk or negedge resetb)
	if(resetb==1'b0)
		black_mark <= 0;
	else if(set_addr==16'hE000 && set_d_ok==1'b1) begin
	        if(set_data[3:0]==4'hE)
		        black_mark <= 1;	
	        else
		        black_mark <= 0;
		end
			
endmodule